#include "include/mm.h"
#include "include/sched.h"
#include "include/tss.h"
#include "include/print.h"
#include "include/interrupt.h"
#include "include/syscall.h"
#include "include/vesa.h"

int main() {
  // *((unsigned long*)0x30000) = 0; /* [Test] Turn off identity mapping, LV-4 root page table item 0 */
  mm_init(); // Initialize linear mapping
  interrupt_init(); // Initialize interrupt
  syscall_init(); // Initialize system call
  vesa_init(); // Initialize VESA
  
  __asm__ ("sti"); // Set flag register IF bit to enable interrupt, before entering user mode
  sched_init(); // Initialize user task
  tss_init(); // Initialize task state segment

  // print(0x9901);
  // print(current->pml4);
  // print(current->rsp0); /* 0, uninitialized ? => should be task kstack top (= kstack base + 8B * 5) */

  init_8254();
  __asm__ ("mov %0, %%cr3": :"r"(current->pml4)); // set cr3 register to current process level 4 page table

  // set %rsp register as the top of the kernel stack that preserves the process context,
  // before `iretq` jump from kernel to user state
  __asm__ ("movq %0, %%rsp\n\t"
           "push %1\n\t"
           "ret" /* RIP pointer to the current process rip */
           :
           : "m"(current->rsp0), /* index 0 */
             "m"(current->rip) /* index 1 */
  );
}